import querystring from 'querystring'
import storage from 'localStorage'
import toastr from 'toastr'
import axios from 'axios'
import Vue from 'vue'

const base = 'http://localhost:8080'

export const http = axios.create({
  baseURL: base,
  timeout: 10000,
  withCredentials: true,
  headers: {'X-Requested-With': 'XMLHttpRequest'},
  transformRequest: [data => {
    return querystring.stringify(data)
  }]
})

// Add a response interceptor
http.interceptors.response.use(response => {
  return response
}, error => {
  var response = error.response
  if (!response) {
    return toastr.info('服务器太久没有响应, 请重试!')
  }
  if (response.status === 401) { // Unauthorized, redirect to login
    toastr.info('会话已过期, 请重新登录')
    storage.removeItem('user')
    return window.location.href = '#/login'
  }
  console.info(response.data)
  toastr.error(response.data.msg)
  return Promise.reject(error)
})

Vue.prototype.$http = http

export const Department = resource('department', http, {
  treetable: () => http.get('department/treetable'),
  jstree: (selected) => http.get('department/jstree', {params: {selected: [].concat(selected || '')}}),  // 获取所有部门
  tree: () => http.get('department/tree'),
  all: () => http.get('department/all'),  // 获取所有部门
  _new: () => http.get('department/new')
})

export const Permission = resource('permission', http, {
  treetable: () => http.get('permission/treetable'),
  menus: () => http.get('permission/menus'),
  perms: () => http.get('permission/perms'),
  jstree: () => http.get('permission/jstree'),
  tree: () => http.get('permission/tree'),
  _new: () => http.get('permission/new')
})

export const User = resource('user', http, {
  current: request => {
    if (request) {
      return http.get('user/current')
    }
    var value = storage.getItem('user')
    if (value) {
      return JSON.parse(value)
    }
  },
  paging: params => http.get('user', {params}),
  query: params => http.get('user/query', {params}),
  /*
   * 搜索用户
   * keyword        搜索关键字
   * type           过滤用户类型
   * dept           过滤部门ID
   * include        需包含的用户
   * excludeCurrent 是否排除当前用户
   */
  search: params => http.get('user/search', {params}),
  roles: (id = '') => http.get('user/roles?id=' + id),  // 获取所有用户
  profile (user) {
    if (user) {
      return http.put('user/profile', user)
    }
    return http.get('user/profile')
  },
  status: (id, status) => http.put('user/status', {id, status}), // 更新状态
  role: (id, roleId) => http.put('user/role', {id, roleId}), // 更新角色
  partial: (params) => http.put('user/partial', params)     // 局部更新用户信息
})

export const Role = resource('role', http, {
  perms: (id) => http.get('role/perms?id=' + id),
  owns: (id) => http.get('role/owns?id=' + id || ''),
  all: () => http.get('role/all'),
  map: () => http.get('role/map')
})

export const Dict = resource('dict', http, {
  byCode: (code) => http.get(`dict/bycode?code=${code}`)
})

export const Auth = {
  authorizationCheck() { // 登录验证
    return new Promise((resolve, reject) => {
      try {
        http.get('/').then(resolve, reject)
      } catch (e) {
        storage.removeItem('user')
        reject(response)
      }
    })
  },
  login: (data) => {
    return new Promise((resolve, reject) => {
      http.post('/guest/login', data).then(response => {
        if (response.data.success) {
          storage.setItem('user', JSON.stringify(response.data.user))
        }
        resolve(response)
      }, reject).catch(reject)
    })
  },
  logout: (to, from, next) => {
    console.log('logout')
    storage.removeItem('user')
    http.get('/logout').then(next('/login'), next('/login'))
  },
  isLogin() {
    try {
      return User.current()
    } catch (e) {
      toastr.error('用户信息出错，请重新登录!')
    }
  }
}

/**
 * create vue-resource's resource like object
 *
 * Default Actions
 *   get: {method: 'GET'}
 *   save: {method: 'POST'}
 *   query: {method: 'GET'}
 *   update: {method: 'PUT'}
 *   delete: {method: 'DELETE'}
 *
 * @param path the resource path
 * @param http axios instance
 * @param actions custom actions
 * @returns the resource object
 */
function resource (path, http, actions) {
  var obj = {
    get: id => http.get(path + '/' + id),
    save: obj => http.post(path, obj),
    query: params => http.get(path, {params}),
    update: obj => http.put(path, obj),
    delete: id => http.delete(path + '/' + id)
  }
  return Object.assign(obj, actions)
}